﻿namespace Viz
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Xna.Framework.Graphics;
    using System.Windows.Media.Imaging;
    using System.IO;
    using System.Threading;
    using System.Windows.Graphics;
    using Microsoft.Xna.Framework.Content;

    public class ShaderTools
    {
        private static ShaderTools                          _instance;

        public static ShaderTools Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new ShaderTools();

                return _instance;
            }
        }

        public Texture2D GetTexture(GraphicsDevice device, string url)
        {
            Stream stream = GetStream(new Uri(url, UriKind.Relative));

            var image = new BitmapImage();
            image.SetSource(stream);
      
            Texture2D texture = new Texture2D(device, image.PixelWidth, image.PixelHeight, false, SurfaceFormat.Color);

            image.CopyTo(texture);

            return texture;
        }

        public Texture2D GetTextureFromWriteableBitmap(GraphicsDevice device, WriteableBitmap bmp)
        {
            Texture2D texture = new Texture2D(device, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);

            bmp.CopyTo(texture);
            return texture;
        }

        public Stream GetStream(Uri uri)
        {
            if (uri == null)
                return null;

            return Application.GetResourceStream(uri).Stream;
        }

        public Texture2D GetTexture(
            FrameworkElement                            context, 
            string                                      text,
            double                                      size,
            Color                                       c, 
            Color                                       b,
            string                                      fontName
        )
        {
            WriteableBitmap                             bmp = null;
            Texture2D                                   t = null;
            var                                         g = GraphicsDeviceManager.Current;
            AutoResetEvent                              textEvent = new AutoResetEvent(false);

            lock(_instance)
            {
                context.Dispatcher.BeginInvoke(() =>
                {
                    TextBlock tb = new TextBlock();

                    (context as Grid).Background = new System.Windows.Media.SolidColorBrush(b);

                    tb.Foreground          = new System.Windows.Media.SolidColorBrush(c);
                    tb.FontSize            = size;
                    tb.Text                = text;
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.VerticalAlignment   = System.Windows.VerticalAlignment.Stretch;
                    tb.FontFamily          = new FontFamily(fontName);

                    bmp = new WriteableBitmap(tb, null);
                    t   = new Texture2D(g.GraphicsDevice, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);

                    bmp.CopyTo(t);
                    textEvent.Set();
                });
                textEvent.WaitOne();
            }
            return t;
        }
    }
}
